/*
Miranda IM for Windows Search

Copyright (C) 2012 Nikolay Raspopov

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#pragma once

#include "MirandaSearch.h"

class CFilter;

// CMirandaFilter

class ATL_NO_VTABLE CMirandaFilter :
	public CComObjectRootEx< CComMultiThreadModel >,
	public CComCoClass< CMirandaFilter, &CLSID_MirandaFilter>,
	public IFilter
{
public:
	CMirandaFilter();

DECLARE_REGISTRY_RESOURCEID(IDR_MIRANDAFILTER)

BEGIN_COM_MAP(CMirandaFilter)
	COM_INTERFACE_ENTRY(IFilter)
END_COM_MAP()

DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct();
	void FinalRelease();

	STDMETHOD(Init)(const CString& sURL, const CString& sRelativeURL , URLLevel nLevel);
	inline const CString& GetURL() const { return m_sURL; }

protected:
	URLLevel			m_nURLLevel;
	CString				m_sURL;				// Original full URL: "miranda://{SID}/[contact[/event]]"
	CString				m_sRelativeURL;		// Relative decoded URL: "/[contact[/event]]"

	ULONG				m_nChunkID;			// Current chunk number
	CComPropVariant		m_pvValue;			// Current chunk value
	bool				m_bValueValid;		// Is current chunk value valid?

	CAutoPtr< CFilter >	m_pFilter;

	// IFilter
	STDMETHOD(Init)(/* [in] */ ULONG grfFlags, /* [in] */ ULONG cAttributes, /* [size_is][in] */ const FULLPROPSPEC *aAttributes, /* [out] */ ULONG *pFlags);
	STDMETHOD(GetChunk)(/* [out] */ STAT_CHUNK *pStat);
	STDMETHOD(GetText)(/* [out][in] */ ULONG *pcwcBuffer, /* [size_is][out] */ WCHAR *awcBuffer);
	STDMETHOD(GetValue)(/* [out] */ PROPVARIANT **ppPropValue);
	STDMETHOD(BindRegion)(/* [in] */ FILTERREGION origPos,/* [in] */ REFIID riid, /* [out] */ void **ppunk);
};

OBJECT_ENTRY_AUTO(__uuidof(MirandaFilter), CMirandaFilter)

class CFilter
{
public:
	CFilter();
	virtual ~CFilter();

	const CMirandaFilter*	m_pOwner;

	STDMETHOD(Init)(LPCSTR szURL) = 0;
	STDMETHOD(GetChunk)(STAT_CHUNK* pStat, CComPropVariant& vValue);

	// VT_EMPTY
	void Add(const PROPERTYKEY& key);

	// PKEY_Search_UrlToIndexWithModificationTime + VT_VECTOR | ( VT_LPCWSTR | VT_FILETIME )
	void AddUrl(LPCWSTR szURL, const FILETIME& ftTimestamp);

	template< typename T>
	void Add(const PROPERTYKEY& key, const T& szValue);

	// VT_VECTOR | ( VT_LPCWSTR )
	void AddVector(const PROPERTYKEY& key, size_t n, ...);

private:
	class CItem
	{
	public:
		FULLPROPSPEC		m_Attribute;
		CComPropVariant		m_pvValue;
	};

	CAtlList< CItem* >		m_nProperties;
	POSITION				m_posPropertiesEnum;
};

class CContacts : public CFilter
{
public:
	STDMETHOD(Init)(LPCSTR szURL);
};

class CEvents : public CFilter
{
public:
	STDMETHOD(Init)(LPCSTR szURL);
};

class CMessage : public CFilter
{
public:
	STDMETHOD(Init)(LPCSTR szURL);
};
